﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System.Xml.Linq;

namespace vxi.com.appsetting
{
    public class Setting
    {
        private GlobalSetting globalSetting;

        public GlobalSetting GlobalSetting
        {
            get { return globalSetting; }
            set { globalSetting = value; }
        }

        private static XmlElement CreateElement(XmlDocument doc, string elementName, string innerText)
        {
            XmlElement xmlElement = doc.CreateElement(elementName);
            xmlElement.InnerText = innerText;
            return xmlElement;
        }

        public void LoadSetting(string filePath)
        {
            string fileName = "AppSetting.xml";
            filePath = Path.Combine(filePath, fileName);

            if (!File.Exists(filePath))
            {
                CreateSettingFile(filePath);
            }
            XmlDocument doc = new XmlDocument();
            doc.Load(filePath);
            this.globalSetting = LoadGlobalSetting(doc.DocumentElement);
        }

        private GlobalSetting LoadGlobalSetting(XmlNode xmlNode)
        {
            GlobalSetting etGlobalSetting = new GlobalSetting();
            foreach (XmlNode item in xmlNode.ChildNodes)
            {
                switch (item.Name)
                {
                    case "SERVER_PORT":
                        etGlobalSetting.SERVER_PORT = int.Parse(item.InnerText);
                        break;
                    case "SERVER_SYNC_PROT":
                        etGlobalSetting.SERVER_SYNC_PROT = int.Parse(item.InnerText);
                        break;
                    case "SYNC_SERVERS":
                        foreach (XmlNode child in item.ChildNodes)
                        {
                            IPEndPoint ip = new IPEndPoint(IPAddress.Parse(child.Attributes["IP"].InnerText), int.Parse(child.Attributes["PORT"].InnerText));
                            etGlobalSetting.SYNC_SERVER.Add(ip);
                        }
                        break;
                    default: break;
                }
            }

            return etGlobalSetting;
        }

        public void  SaveSetting(string filePath)
        {
            StringBuilder xml = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            xml.Append(Environment.NewLine);
            xml.Append(@"<GlobalSetting>");
            xml.Append(Environment.NewLine);
            xml.AppendFormat(@" <SERVER_PORT>{0}</SERVER_PORT>",globalSetting.SERVER_PORT);
            xml.Append(Environment.NewLine);
            xml.AppendFormat(@" <SERVER_SYNC_PROT>{0}</SERVER_SYNC_PROT>", globalSetting.SERVER_SYNC_PROT);
            xml.Append(Environment.NewLine);
            xml.Append(@"   <SYNC_SERVERS>");
            foreach (IPEndPoint ip in globalSetting.SYNC_SERVER)
            {
                xml.Append(Environment.NewLine);
                xml.AppendFormat("     <SYNC_SERVER IP=\"{0}\" PORT=\"{1}\"></SYNC_SERVER>", ip.Address, ip.Port);
            }
            xml.Append(Environment.NewLine);
            xml.Append(@"   </SYNC_SERVERS>");
            xml.Append(Environment.NewLine);
            xml.Append(@" </GlobalSetting>");
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml.ToString());
            try
            {
                doc.Save(Path.Combine(filePath, "AppSetting.xml"));
            }
            catch (Exception e)
            {

            }
        }




        private static void CreateSettingFile(string filePath)
        {
            string xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
                        + "<GlobalSetting>"
                        + "<SERVER_PORT>2280</SERVER_PORT>"
                        + "<SERVER_SYNC_PROT>4560</SERVER_SYNC_PROT>"
                        + "</GlobalSetting>";
            StreamWriter sw = File.CreateText(filePath);
            sw.Write(xml);
            sw.Flush();
            sw.Close();
            sw.Dispose();
        }



        /// <summary>
        /// 进行DES加密。
        /// </summary>
        /// <param name="pToEncrypt">要加密的字符串。</param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <returns>以Base64格式返回的加密字符串。</returns>
        private static string Encrypt(string pToEncrypt, string sKey)
        {
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                byte[] inputByteArray = Encoding.UTF8.GetBytes(pToEncrypt);
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Convert.ToBase64String(ms.ToArray());
                ms.Close();
                return str;
            }
        }

        /// <summary>
        /// 进行DES解密。
        /// </summary>
        /// <param name="pToDecrypt">要解密的以Base64</param>
        /// <param name="sKey">密钥，且必须为8位。</param>
        /// <returns>已解密的字符串。</returns>
        private static string Decrypt(string pToDecrypt, string sKey)
        {
            byte[] inputByteArray = Convert.FromBase64String(pToDecrypt);
            using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
            {
                des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
                des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(inputByteArray, 0, inputByteArray.Length);
                    cs.FlushFinalBlock();
                    cs.Close();
                }
                string str = Encoding.UTF8.GetString(ms.ToArray());
                ms.Close();
                return str;
            }
        }        
    }
}
